package com.hcc.flow.server.config;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import com.alibaba.fastjson.JSONObject;
import com.hcc.flow.server.common.model.ApiResult;
import com.hcc.flow.server.common.utils.HttpHelper;
import com.hcc.flow.server.common.utils.ResponseUtil;
import com.hcc.flow.server.filter.TokenFilter;
import com.hcc.flow.server.model.common.LoginUser;
import com.hcc.flow.server.model.common.Token;
import com.hcc.flow.server.service.sys.TokenService;

/**
 * spring security处理器
 * 
 * @author 韩长长 
 *
 * 
 */
@Configuration
public class SecurityHandlerConfig {

	@Autowired
	private TokenService tokenService;
	
	/**
	 * 登陆成功，返回Token
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationSuccessHandler loginSuccessHandler() {
		return new AuthenticationSuccessHandler() {

			@Override
			public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				LoginUser loginUser = (LoginUser) authentication.getPrincipal();
				Token token = tokenService.saveToken(loginUser);
				token.setSysid(validate(request));
				ResponseUtil.responseJson(response, HttpStatus.OK.value(), token);
			}
		};
	}
	
	private String validate(HttpServletRequest request) throws IOException {
		ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
		String json = HttpHelper.getBodyString(requestWrapper);
		if (json.contains("param") && json.contains("{")) {
			JSONObject jsonObject = JSONObject.parseObject(json);
			json = jsonObject.get("param").toString();
		}
		if (json.contains("sysid") && json.contains("{")) {
			JSONObject jsonObject = JSONObject.parseObject(json);
			return jsonObject.getString("sysid");
		}
		return null;
	}
	
	/**
	 * 登陆失败
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationFailureHandler loginFailureHandler() {
		return new AuthenticationFailureHandler() {

			@Override
			public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException exception) throws IOException, ServletException {
				String msg = null;
				if (exception instanceof BadCredentialsException) {
					msg = "密码错误";
				} else {
					msg = exception.getMessage();
				}
				// ResponseInfo info = new
				// ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", msg);
				ApiResult<String> info = new ApiResult<String>();
				info.setCode("200");
				info.setMsg(msg);
				info.setStatusCode("1");
				info.setData("");
				ResponseUtil.responseJson(response, HttpStatus.OK.value(), info);
			}
		};
	}

	/**
	 * 未登录，返回401
	 * 
	 * @return
	 */
	@Bean
	public AuthenticationEntryPoint authenticationEntryPoint() {
		return new AuthenticationEntryPoint() {

			@Override
			public void commence(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException authException) throws IOException, ServletException {
				// ResponseInfo info = new
				// ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", "请先登录");
				ApiResult<String> info = new ApiResult<String>();
				info.setCode("401");
				info.setMsg("请重新登录,具体原因：" + authException.getMessage());
				info.setStatusCode("1");
				info.setData("");
				ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), info);
			}
		};
	}

	/**
	 * 退出处理
	 * 
	 * @return
	 */
	@Bean
	public LogoutSuccessHandler logoutSussHandler() {
		return new LogoutSuccessHandler() {

			@Override
			public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				// ResponseInfo info = new ResponseInfo(HttpStatus.OK.value() +
				// "", "退出成功");
				ApiResult<String> info = new ApiResult<String>();
				info.setCode("200");
				info.setMsg("退出成功");
				info.setStatusCode("0");
				info.setData("");
				String token = TokenFilter.getToken(request);
				tokenService.deleteToken(token);
				ResponseUtil.responseJson(response, HttpStatus.OK.value(), info);
			}
		};
	}

}
